package GUIComponents.HlavniKomponentyComponents;

import Jama.EigenvalueDecomposition;
import Jama.Matrix;
import statistics.poznavaniTextu.E2;
import statistics.poznavaniTextu.Elipsa;
import statistics.poznavaniTextu.PointBasen;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;

/*
*   File Gr2 
*   in package GUIComponents.HlavniKomponentyComponents
*   was created by slaha
*   on 30.4.12 at 21:13.
*
*/
public class Gr2 extends JPanel{

  final int px = 20;
  HashMap<String, ArrayList<PointBasen>> autoriBody = new HashMap<>();

  public Gr2(HashMap<String, ArrayList<PointBasen>> autoriBody) {
    this.autoriBody = autoriBody;
  }

  protected void paintComponent(Graphics gr) {
    Graphics2D g = (Graphics2D) gr;
    double w = getWidth()*0.5;
    double h = getHeight()*0.5;

    gr.translate((int) w, (int) h);

    for(String autor : autoriBody.keySet()) {
      for (PointBasen p : autoriBody.get(autor)) {
        int xx = (int) Math.round(p.x * px);
        int yy = (int) Math.round(p.y * px);
        g.fillRect(xx-2, yy-2, 4, 4);
      }

      double[][] m = dejMaticiAutora(autor);
      Matrix matrixAutora = new Matrix(m);

      E2 el = new E2(autoriBody.get(autor), px, px);


      Elipsa e = dejElipsu(matrixAutora, w, h, el);
      e.paint(g);
      ArrayList<PointBasen> bodyAL = e.getBody();

      for (int i = 0; i < bodyAL.size()-1; i++) {
        PointBasen p = bodyAL.get(i);
        PointBasen k = bodyAL.get(i + 1);
        g.drawLine((int)p.x, (int)p.y, (int)k.x, (int)k.y);
      }

    }



    gr.translate(-(int) w, -(int) h);
  }

  Elipsa dejElipsu(Matrix matrix, double x, double y, E2 el) {
    Matrix inverzni;
    double[][] kovariancniMatice = dejKovariancniMatici(matrix);
    inverzni = new Matrix(kovariancniMatice).inverse();
    EigenvalueDecomposition eig = inverzni.eig();
    double[] vlCisla = eig.getRealEigenvalues();


    return new Elipsa(x, y, vlCisla[0], vlCisla[1], eig.getV().getArray(), px, px);
    //return new Elipsa(x, y, eig);
  }

  double[][] dejMaticiAutora(String autor) {
    double[][] m = new double[autoriBody.get(autor).size()][2];
    int i = 0;
    for (PointBasen point : autoriBody.get(autor)) {
      m[i][0] = point.x;
      m[i][1] = point.y;
      i++;
    }

    return m;
  }

  private double[][] dejKovariancniMatici(Matrix m) {
    double[][] kM = new double[2][2];

    kM[0][0] = kovariance(0, 0, m);
    kM[0][1] = kovariance(0, 1, m);
    kM[1][0] = kM[0][1];
    kM[1][1] = kovariance(1, 1, m);

    return kM;
  }

  private double kovariance(int jevX, int jevY, Matrix m) {
    double kovariance = 0d;
    double n_1 = (double) m.getRowDimension() - 1;
    double prumerX = prumer(m, jevX);
    double prumerY = prumer(m, jevY);

    for (int i = 0; i < m.getRowDimension(); i++) {
      double x = m.get(i, jevX);
      double y = m.get(i, jevY);

      double clen1 = x - prumerX;
      double clen2 = y - prumerY;
      kovariance += (clen1 * clen2);
    }

    return (kovariance / n_1);
  }

  double prumer(Matrix m, int sloupec) {
    double prumer = 0d;

    for (double d : m.getMatrix(0, m.getRowDimension() - 1, sloupec, sloupec).getRowPackedCopy()) {
      prumer += d;
    }

    return prumer / m.getRowDimension();
  }
}
